#include <SIMULATE_SIGNAL_module/SIMULATE_SIGNAL.hpp>

#ifdef DBG_TAG
#undef DBG_TAG
#endif
#ifdef DBG_LVL
#undef DBG_LVL
#endif

#define DBG_TAG     "simu_signal"
#define DBG_LVL     DBG_LOG

extern "C"
{
#include <rtdbg.h>
}

using namespace std;

/******************************************************************************
 *
 * @brief:     SIMULATE_SIGNAL类实现
 *
 ******************************************************************************/
SIMULATE_SIGNAL::SIMULATE_SIGNAL(CHIP_OUTPUT_PIN *A_pin,
                                 CHIP_OUTPUT_PIN *B_pin,
                                 uint32_t min_cycle_time)
{
    if (!A_pin || !B_pin)
    {
        LOG_E("input pin A or B is NULL");
        goto end;
    }

    this->A_pin = A_pin;
    this->B_pin = B_pin;
    this->min_cycle_time = min_cycle_time;

    if (A_pin->CHIP_OUTPUT_read_init_status() != chip_pin_status_ok
            || B_pin->CHIP_OUTPUT_read_init_status() != chip_pin_status_ok)
    {
        LOG_E("input pin A or B is not init ok");
        goto end;
    }

    signal_sem = rt_sem_create("sig_sem", 0, RT_IPC_FLAG_PRIO);
    if (!signal_sem)
    {
        LOG_E("signal sem is not init ok");
        goto end;
    }

    A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
    B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
    LOG_I("simulate signal init ok");
    init_flag = simulate_signal_status_ok;
    return;
    end:
    LOG_E("simulate signal init fail");
    init_flag = simulate_signal_status_fail;
}

void SIMULATE_SIGNAL::SIMULATE_SIGNAL_in_thread_function()
{
    if (init_flag != simulate_signal_status_ok) while (1)
    {
        LOG_E("simulate signal not init ok,pls contact tech");
        rt_thread_mdelay(1000);
    }

    while (1)
    {
        rt_sem_take(signal_sem, RT_WAITING_FOREVER);
        A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_HIGH);
        B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);

        rt_hw_us_delay(min_cycle_time / 4);
        B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_HIGH);
        rt_hw_us_delay(min_cycle_time / 4);
        A_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
        rt_hw_us_delay(min_cycle_time / 4);
        B_pin->CHIP_OUTPUT_PIN_write(chip_pin_level_LOW);
        rt_hw_us_delay(min_cycle_time / 4);

    }

}

void SIMULATE_SIGNAL::SIMULATE_SIGNAL_add_a_signal()
{
    if (init_flag != simulate_signal_status_ok) return;

    rt_sem_release(signal_sem);
}
